package user

import (
	"context"
	"cs0512/fmr/internal/apiserver/store"
	"cs0512/fmr/pkg/model"
	"errors"
)

type UserSrv interface {
	GetUserByUid(ctx context.Context, uid int) (*model.User, error)
	GetUserByUsername(ctx context.Context, username string) (*model.User, error)
	Create(ctx context.Context, user *model.User) error
	CheckLogin(ctx context.Context, username, password string) (*model.User, error)
	Update(ctx context.Context, user *model.User) error
	ChangePassword(ctx context.Context, uid int, password string) error
	CloseUser(ctx context.Context, uid int) error
	DeleteUser(ctx context.Context, uid int) error
	List(ctx context.Context, opt model.UserOptions) (*model.UserList, error)
}

type userService struct {
	store store.Factory
}

var _ UserSrv = (*userService)(nil)

func New(db store.Factory) *userService {
	return &userService{
		store: db,
	}
}

func (us *userService) GetUserByUid(ctx context.Context, uid int) (*model.User, error) {
	return us.store.Users().Get(ctx, uid)
}

func (us *userService) GetUserByUsername(ctx context.Context, username string) (*model.User, error) {
	return us.store.Users().GetByUsername(ctx, username)
}

// 创建新用户
func (us *userService) Create(ctx context.Context, user *model.User) error {
	user.CreatePassword(user.Password)
	err := us.store.Users().Create(ctx, user)
	if err != nil {
		return err
	}
	return nil
}

// 更新用户信息
func (us *userService) Update(ctx context.Context, user *model.User) error {
	userModel, err := us.store.Users().Get(ctx, user.ID)
	if err != nil {
		return err
	}
	if user.Username != "" {
		userModel.Username = user.Username
	}
	userModel.Role = user.Role
	userModel.Status = user.Status
	if user.Password != "" {
		userModel.CreatePassword(user.Password)
	}
	userModel.Mobile = user.Mobile
	err = us.store.Users().Update(ctx, userModel)
	if err != nil {
		return err
	}

	return nil
}

// 用户登录
func (us *userService) CheckLogin(ctx context.Context, username, password string) (*model.User, error) {
	mu, err := us.store.Users().GetByUsername(ctx, username)
	if err != nil {
		return nil, err
	}
	if mu.Status == 0 {
		return nil, errors.New("Account is closed.")
	}
	if !mu.CheckPassword(password) {
		return nil, errors.New("Username or password is incorrect!")
	}

	us.store.Users().Update(ctx, mu)

	return mu, nil
}

// 修改密码
func (us *userService) ChangePassword(ctx context.Context, uid int, password string) error {
	user, err := us.store.Users().Get(ctx, uid)
	if err != nil {
		return err
	}
	user.CreatePassword(password)
	return us.store.Users().Update(ctx, user)
}

// 关闭用户
func (us *userService) CloseUser(ctx context.Context, uid int) error {
	user, err := us.store.Users().Get(ctx, uid)
	if err != nil {
		return err
	}
	user.Status = 0
	err = us.store.Users().Update(ctx, user)
	if err != nil {
		return err
	}
	return nil
}

// 删除用户
func (us *userService) DeleteUser(ctx context.Context, uid int) error {
	return us.store.Users().Delete(ctx, uid)
}

func (us *userService) List(ctx context.Context, opt model.UserOptions) (*model.UserList, error) {
	return us.store.Users().List(ctx, opt)
}
